1   /*
2    * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   */
23  
24  /*
25   * @test
26   * @summary Unit test for java.net.CookieManager
27   * @bug 6244040
28   * @library ../../../sun/net/www/httptest/
29   * @build HttpCallback HttpServer ClosedChannelList HttpTransaction
30   * @run main/othervm -ea CookieManagerTest
31   * @author Edward Wang
32   */
33  
34  import java.net.*;
35  import java.util.*;
36  import java.io.*;
37  import sun.net.www.MessageHeader;
38  
39  public class CookieManagerTest {
40      static CookieHttpTransaction httpTrans;
41      static HttpServer server;
42  
43      public static void main(String[] args) throws Exception {
44          startHttpServer();
45          makeHttpCall();
46  
47          if (httpTrans.badRequest) {
48              throw new RuntimeException("Test failed : bad cookie header");
49          }
50      }
51  
52      public static void startHttpServer() {
53          try {
54              httpTrans = new CookieHttpTransaction();
55              server = new HttpServer(httpTrans, 1, 1, 0);
56          } catch (IOException e) {
57              e.printStackTrace();
58          }
59      }
60  
61      public static void makeHttpCall() {
62          try {
63              System.out.println("http server listen on: " + server.getLocalPort());
64  
65              // install CookieManager to use
66              CookieHandler.setDefault(new CookieManager());
67  
68              for (int i = 0; i < CookieHttpTransaction.testCount; i++) {
69                  System.out.println("====== CookieManager test " + (i+1) + " ======");
70                  ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(CookieHttpTransaction.testPolicies[i]);
71                  ((CookieManager)CookieHandler.getDefault()).getCookieStore().removeAll();
72                  URL url = new URL("http" , InetAddress.getLocalHost().getHostAddress(),
73                                      server.getLocalPort(), CookieHttpTransaction.testCases[i][0].serverPath);
74                  HttpURLConnection uc = (HttpURLConnection)url.openConnection();
75                  uc.getResponseCode();
76                  uc.disconnect();
77              }
78          } catch (IOException e) {
79              e.printStackTrace();
80          } finally {
81              server.terminate();
82          }
83      }
84  }
85  
86  class CookieHttpTransaction implements HttpCallback {
87      public static boolean badRequest = false;
88      // the main test control logic will also loop exactly this number
89      // to send http request
90      public static final int testCount = 6;
91  
92      private String localHostAddr = "127.0.0.1";
93  
94      // test cases
95      public static class CookieTestCase {
96          public String headerToken;
97          public String cookieToSend;
98          public String cookieToRecv;
99          public String serverPath;
100 
101         public CookieTestCase(String h, String cts, String ctr, String sp) {
102             headerToken = h;
103             cookieToSend = cts;
104             cookieToRecv = ctr;
105             serverPath = sp;
106         }
107     };
108 
109     //
110     // these two must match each other, i.e. testCases.length == testPolicies.length
111     //
112     public static CookieTestCase[][] testCases = null;  // the test cases to run; each test case may contain multiple roundtrips
113     public static CookiePolicy[] testPolicies = null;   // indicates what CookiePolicy to use with each test cases
114 
115     CookieHttpTransaction() {
116         testCases = new CookieTestCase[testCount][];
117         testPolicies = new CookiePolicy[testCount];
118 
119         try {
120             localHostAddr = InetAddress.getLocalHost().getHostAddress();
121         } catch (Exception ignored) {
122         };
123         int count = 0;
124 
125         // an http session with Netscape cookies exchanged
126         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
127         testCases[count++] = new CookieTestCase[]{
128                 new CookieTestCase("Set-Cookie",
129                 "CUSTOMER=WILE:BOB; path=/; expires=Wednesday, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr,
130                 "CUSTOMER=WILE:BOB",
131                 "/"
132                 ),
133                 new CookieTestCase("Set-Cookie",
134                 "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr,
135                 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001",
136                 "/"
137                 ),
138                 new CookieTestCase("Set-Cookie",
139                 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr,
140                 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001",
141                 "/"
142                 ),
143                 new CookieTestCase("Set-Cookie",
144                 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr,
145                 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX",
146                 "/foo"
147                 )
148                 };
149 
150         // check whether or not path rule is applied
151         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
152         testCases[count++] = new CookieTestCase[]{
153                 new CookieTestCase("Set-Cookie",
154                 "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr,
155                 "PART_NUMBER=ROCKET_LAUNCHER_0001",
156                 "/"
157                 ),
158                 new CookieTestCase("Set-Cookie",
159                 "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo;" + "domain=." + localHostAddr,
160                 "PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001",
161                 "/ammo"
162                 )
163                 };
164 
165         // an http session with rfc2965 cookies exchanged
166         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
167         testCases[count++] = new CookieTestCase[]{
168                 new CookieTestCase("Set-Cookie2",
169                 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
170                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
171                 "/acme/login"
172                 ),
173                 new CookieTestCase("Set-Cookie2",
174                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr,
175                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr +  "\"",
176                 "/acme/pickitem"
177                 ),
178                 new CookieTestCase("Set-Cookie2",
179                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
180                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
181                 "/acme/shipping"
182                 )
183                 };
184 
185         // check whether or not the path rule is applied
186         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
187         testCases[count++] = new CookieTestCase[]{
188                 new CookieTestCase("Set-Cookie2",
189                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
190                 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
191                 "/acme/ammo"
192                 ),
193                 new CookieTestCase("Set-Cookie2",
194                 "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." + localHostAddr,
195                 "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
196                 "/acme/ammo"
197                 ),
198                 new CookieTestCase("",
199                 "",
200                 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
201                 "/acme/parts"
202                 )
203                 };
204 
205         // new cookie should overwrite old cookie
206         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
207         testCases[count++] = new CookieTestCase[]{
208                 new CookieTestCase("Set-Cookie2",
209                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
210                 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
211                 "/acme"
212                 ),
213                 new CookieTestCase("Set-Cookie2",
214                 "Part_Number=\"Rocket_Launcher_2000\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
215                 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
216                 "/acme"
217                 )
218                 };
219 
220         // cookies without domain attributes
221         // RFC 2965 states that domain should default to host
222         testPolicies[count] = CookiePolicy.ACCEPT_ALL;
223         testCases[count++] = new CookieTestCase[]{
224                 new CookieTestCase("Set-Cookie2",
225                 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"",
226                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
227                 "/acme/login"
228                 ),
229                 new CookieTestCase("Set-Cookie2",
230                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"",
231                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
232                 "/acme/pickitem"
233                 ),
234                 new CookieTestCase("Set-Cookie2",
235                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"",
236                 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"",
237                 "/acme/shipping"
238                 )
239                 };
240 
241         assert count == testCount;
242     }
243 
244     private int testcaseDone = 0;
245     private int testDone = 0;
246     /*
247      * Our http server which is conducted by testCases array
248      */
249     public void request(HttpTransaction trans) {
250         try {
251             if (testDone < testCases[testcaseDone].length) {
252                 // still have other tests to run,
253                 // check the Cookie header and then redirect it
254                 if (testDone > 0) checkResquest(trans);
255                 trans.addResponseHeader("Location", testCases[testcaseDone][testDone].serverPath);
256                 trans.addResponseHeader(testCases[testcaseDone][testDone].headerToken,
257                                         testCases[testcaseDone][testDone].cookieToSend);
258                 testDone++;
259                 trans.sendResponse(302, "Moved Temporarily");
260             } else {
261                 // the last test of this test case
262                 if (testDone > 0) checkResquest(trans);
263                 testcaseDone++;
264                 testDone = 0;
265                 trans.sendResponse(200, "OK");
266             }
267         } catch (Exception e) {
268             e.printStackTrace();
269         }
270     }
271 
272     private void checkResquest(HttpTransaction trans) {
273         String cookieHeader = null;
274 
275         assert testDone > 0;
276         cookieHeader = trans.getRequestHeader("Cookie");
277         if (cookieHeader != null &&
278             cookieHeader.equalsIgnoreCase(testCases[testcaseDone][testDone-1].cookieToRecv))
279         {
280             System.out.printf("%15s %s\n", "PASSED:", cookieHeader);
281         } else {
282             System.out.printf("%15s %s\n", "FAILED:", cookieHeader);
283             System.out.printf("%15s %s\n\n", "should be:", testCases[testcaseDone][testDone-1].cookieToRecv);
284             badRequest = true;
285         }
286     }
287 }